package com.sos.core.cards 
{
	import com.sos.utils.ClassUtils;

	public class CardSubtype
	{
		
		// -------------------------------------------------------------------------------
		// CONSTANTS
		// -------------------------------------------------------------------------------	
		
		// JSON data property definition
		protected static const 	JSON_PROPERTY_CARD_TYPE:String			= "subtype";

		// Enum values
		public static const 	GENERAL:CardSubtype							= new CardSubtype(1, "Action", false);
		public static const 	DEBUFF:CardSubtype							= new CardSubtype(2, "Debuff", true);
		public static const 	BUFF:CardSubtype							= new CardSubtype(3, "Buff", true);
		public static const 	GEAR:CardSubtype							= new CardSubtype(4, "Gear", true);
		public static const 	FREEKICK:CardSubtype						= new CardSubtype(5, "Freekick", false);
		public static const 	SWAP:CardSubtype							= new CardSubtype(6, "Action", false);
		public static const 	CHILD_EFFECT:CardSubtype					= new CardSubtype(7, "Child Effect", false);
		public static const 	FOUL:CardSubtype							= new CardSubtype(8, "Foul", false);
		public static const 	YELLOW_CARD:CardSubtype						= new CardSubtype(9, "Yellow Card", false);
		public static const 	RED_CARD:CardSubtype						= new CardSubtype(10, "Red Card", false);
		public static const 	SCHOOL:CardSubtype							= new CardSubtype(11, "School", false);
		public static const 	STAMINA_REGEN:CardSubtype					= new CardSubtype(12, "Stamina Regen (second half)", false);
		public static const 	CARD_COST:CardSubtype						= new CardSubtype(13, "cardCost", false);
		public static const 	CHILD_DEBUFF:CardSubtype					= new CardSubtype(14, "Child Debuff", true);
		public static const 	CHILD_BUFF:CardSubtype						= new CardSubtype(15, "Child Buff", true);
		public static const 	ANALYSIS_MARKER:CardSubtype					= new CardSubtype(16, "Analysis Marker", true);
		public static const 	INVISIBLE_MARKER:CardSubtype				= new CardSubtype(16, "Invisible Marker", false);
		
		// -------------------------------------------------------------------------------
		// STATIC
		// -------------------------------------------------------------------------------
		
		private static var _initialized:Boolean = false;
		private static var _list:Vector.<CardSubtype>;
		private static var _visible:Boolean;

		// Fake static constructor
		{
			// Fill the internal list
			_list = new Vector.<CardSubtype>();
			_list.push(CardSubtype.GENERAL);
			_list.push(CardSubtype.DEBUFF);
			_list.push(CardSubtype.BUFF);
			_list.push(CardSubtype.GEAR);
			_list.push(CardSubtype.FREEKICK);
			_list.push(CardSubtype.SWAP);
			_list.push(CardSubtype.CHILD_EFFECT);
			_list.push(CardSubtype.FOUL);
			_list.push(CardSubtype.YELLOW_CARD);
			_list.push(CardSubtype.RED_CARD);
			_list.push(CardSubtype.SCHOOL);
			_list.push(CardSubtype.STAMINA_REGEN);
			_list.push(CardSubtype.CARD_COST);
			_list.push(CardSubtype.CHILD_DEBUFF);
			_list.push(CardSubtype.CHILD_BUFF);
			_list.push(CardSubtype.ANALYSIS_MARKER);
			_list.push(CardSubtype.INVISIBLE_MARKER);
			_list.push(CardSubtype.GEAR);
			// Init!
			_initialized = true;
		}
		
		// -------------------------------------------------------------------------------
		// FIELDS
		// -------------------------------------------------------------------------------
		
		private var _id:uint;
		private var _name:String;
		
		// -------------------------------------------------------------------------------
		// CONSTRUCTORS
		// -------------------------------------------------------------------------------
		
		public function CardSubtype(id:uint, name:String, visible:Boolean)
		{
			// Safe unique instance lock
			if (_initialized) throw new Error("CardSubtype enum already created!");
			// Init
			_id = id;
			_name = name;
			_visible = visible;
		}
		
		// -------------------------------------------------------------------------------
		// PROPERTIES
		// -------------------------------------------------------------------------------	

		public function get id():uint
		{
			return _id;
		}
		
		public function get name():String
		{
			return _name;
		}
		
		static public function get visible():Boolean 
		{
			return _visible;
		}
		
		// -------------------------------------------------------------------------------
		// PUBLIC METHODS
		// -------------------------------------------------------------------------------
		
		public function toString():String
		{
			return ClassUtils.getName(this) + "." + _name;
		}
		
		
		// -------------------------------------------------------------------------------
		// STATIC METHODS
		// -------------------------------------------------------------------------------
		
		/**
		 * 
		 * @return 
		 */
		public static function names():Array 
		{
			var list:Array  = new Array ;
			// Loop over values list
			for (var i:int=0; i<_list.length; i++)
			{
				list.push(_list[i].name);
			}
			return list;
		}
		
		/**
		 * 
		 * @return 
		 */
		public static function list():Array
		{
			var list:Array  = new Array ;
			// Loop over values list
			for (var i:int=0; i<_list.length; i++)
			{
				list.push(_list[i]);
			}
			return list;
		}
		
		/**
		 * Search a CardType by given id 
		 * @param id Id of the card type to find
		 * @return CardType constant for the given id, null if no CardType
		 * for the given id has been found
		 */		
		public static function getById(id:uint):CardSubtype
		{
			// Search the value into the list
			for (var i:int=0; i<_list.length; i++)
			{
				if (_list[i].id == id) return _list[i];
			}
			throw new Error("CardSubtype for id '" + id + "' unknown!");
		}
		
		/**
		 * Search a PlayerRole by given name 
		 * @param name Name of the player role to find
		 * @return PlayerRole constant for the given id, null if no PlayerRole
		 * for the given id has been found
		 */		
		public static function getByName(name:String):CardSubtype
		{
			// Search the value into the list
			for (var i:int=0; i<_list.length; i++)
			{
				if (_list[i].name == name) return _list[i];
			}
			throw new Error("CardSubtype for name '" + name + "' unknown!");
		}
		
		/**
		 * Search a PlayerRole by given name 
		 * @param name Name of the player role to find
		 * @return PlayerRole constant for the given id, null if no PlayerRole
		 * for the given id has been found
		 */
		public static function getByObject(obj:Object):CardSubtype
		{
			// Check if the object contains the field to retrieve card type id
			if (!obj.hasOwnProperty(JSON_PROPERTY_CARD_TYPE)) throw new Error("Data not valid! Data object doesn't contains '" + JSON_PROPERTY_CARD_TYPE + "' field!");
			// retrieve CardType id
			var id:uint = uint(obj[JSON_PROPERTY_CARD_TYPE]);
			// Search the value into the list
			for (var i:int=0; i<_list.length; i++)
			{
				if (_list[i].id == id) return _list[i];
			}
			throw new Error("CardSubtype for id '" + id + "' unknown!");
		}
		
	}
}